package perform.mappings;

import java.lang.reflect.Field;

import perform.database.ColumnProcessor;
import perform.type.Type;

public class ManyToManyMapping {
	
	private String name;
	private Class<? extends Type> class1;
	private Class<? extends Type> class2;
	private Field field1;
	private Field field2;
	private String column1;
	private String column2;
	private ColumnProcessor idColumn1;
	private ColumnProcessor idColumn2;
	
	private String insertQuery1;
	private String insertQuery2;
	private String deleteQuery1;
	private String deleteQuery2;
	private String deleteAllQuery1;
	private String deleteAllQuery2;
	private String loadQuery1;
	private String loadQuery2;
	
	public ManyToManyMapping(String name){
		this.name = name;
	}
	
	public void buildQueries(){
		buildInserts();
		buildDeletes();
		buildDeleteAlls();
		buildLoads();
	}
	private void buildInserts(){
		StringBuilder builder1 = new StringBuilder("replace into `").append(name).append("` ( `");
		StringBuilder builder2 = new StringBuilder("replace into `").append(name).append("` ( `");
		builder1.append(column1).append("` , `").append(column2).append("` ) values ( ? , ? ) ;");
		builder2.append(column2).append("` , `").append(column1).append("` ) values ( ? , ? ) ;");
		insertQuery1 = builder1.toString();
		insertQuery2 = builder2.toString();
	}
	private void buildDeletes(){
		StringBuilder builder1 = new StringBuilder("delete from `").append(name).append("` where `");
		StringBuilder builder2 = new StringBuilder("delete from `").append(name).append("` where `");
		builder1.append(column1).append("` = ? and `").append(column2).append("` = ? ;");
		builder2.append(column2).append("` = ? and `").append(column1).append("` = ? ;");
		deleteQuery1 = builder1.toString();
		deleteQuery2 = builder2.toString();
	}
	private void buildDeleteAlls(){
		StringBuilder builder1 = new StringBuilder("delete from `").append(name).append("` where `");
		StringBuilder builder2 = new StringBuilder("delete from `").append(name).append("` where `");
		builder1.append(column1).append("` = ? ;");
		builder2.append(column2).append("` = ? ;");
		deleteAllQuery1 = builder1.toString();
		deleteAllQuery2 = builder2.toString();
	}
	private void buildLoads(){
		String target1 = ClassMappings.getTable(class1);
		String id1 = ClassMappings.getIDColumn(class1);
		String target2 = ClassMappings.getTable(class2);
		String id2 = ClassMappings.getIDColumn(class2);
		StringBuilder builder1 = new StringBuilder("select `").append(target2).append("`.* from `").append(name).append("` inner join `").append(target2)
				.append("` on `").append(name).append("`.`").append(column2).append("` = `").append(target2).append("`.`").append(id2).append("` where `")
				.append(name).append("`.`").append(column1).append("` = ? ;");
		StringBuilder builder2 = new StringBuilder("select `").append(target1).append("`.* from `").append(name).append("` inner join `").append(target1)
				.append("` on `").append(name).append("`.`").append(column1).append("` = `").append(target1).append("`.`").append(id1).append("` where `")
				.append(name).append("`.`").append(column2).append("` = ? ;");
		loadQuery1 = builder1.toString();
		loadQuery2 = builder2.toString();
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Class<? extends Type> getClass1() {
		return class1;
	}
	public void setClass1(Class<? extends Type> class1) {
		this.class1 = class1;
	}
	public Class<? extends Type> getClass2() {
		return class2;
	}
	public void setClass2(Class<? extends Type> class2) {
		this.class2 = class2;
	}
	public Field getField1() {
		return field1;
	}
	public void setField1(Field field1) {
		this.field1 = field1;
	}
	public Field getField2() {
		return field2;
	}
	public void setField2(Field field2) {
		this.field2 = field2;
	}
	public String getColumn1() {
		return column1;
	}
	public void setColumn1(String column1) {
		this.column1 = column1;
	}
	public String getColumn2() {
		return column2;
	}
	public void setColumn2(String column2) {
		this.column2 = column2;
	}
	public ColumnProcessor getIdColumn1() {
		return idColumn1;
	}
	public void setIdColumn1(ColumnProcessor idColumn1) {
		this.idColumn1 = idColumn1;
	}
	public ColumnProcessor getIdColumn2() {
		return idColumn2;
	}
	public void setIdColumn2(ColumnProcessor idColumn2) {
		this.idColumn2 = idColumn2;
	}
	
	public String getInsertQuery(Field sourceField) {
		if(sourceField.equals(field1)){
			return insertQuery1;
		}
		return insertQuery2;
	}
	public String getDeleteQuery(Field sourceField) {
		if(sourceField.equals(field1)){
			return deleteQuery1;
		}
		return deleteQuery2;
	}
	public String getDeleteAllQuery(Field sourceField) {
		if(sourceField.equals(field1)){
			return deleteAllQuery1;
		}
		return deleteAllQuery2;
	}
	public String getLoadQuery(Field sourceField) {
		if(sourceField.equals(field1)){
			return loadQuery1;
		}
		return loadQuery2;
	}

}
